package com.scr1pt.extension

import java.io.File

/**
 * 说明: 文件操作扩展
 *
 * 创建者: tum0r
 *
 * 时间: 2021/8/18 21:06
 */

// region 检查
/**
 * 是否是文件（文件是否存在）
 *
 * @param[ignoreIsHidden] 是否判断被检查的文件是不是隐藏的
 */
@JvmOverloads
fun File.isExistsFile(ignoreIsHidden: Boolean = false): Boolean = this.isFile && (ignoreIsHidden || !this.isHidden)

/**
 * 是否是文件夹（文件夹是否存在）
 *
 * @param[ignoreIsHidden] 是否判断被检查的文件是不是隐藏的
 */
@JvmOverloads
fun File.isExistsFolder(ignoreIsHidden: Boolean = false): Boolean = this.isDirectory && (ignoreIsHidden || !this.isHidden)

/**
 * 检查是否存在目录穿越
 *
 * @param[file] 被检查的文件
 * @return false为存在目录穿越
 */
fun File.checkDirThrough(file: File): Boolean = file.canonicalPath.startsWith(this.canonicalPath)
// endregion

// region 操作文件/文件夹
/**
 * 创建文件夹
 */
fun File.createDir(): Boolean = isExistsFolder() || this.mkdirs()

/**
 * 创建父文件夹
 */
fun File.createParentDir(): Boolean = this.parentFile.createDir()

/**
 * 递归获取某一文件或某一文件夹下所有的文件
 *
 * @param[ignoreIsHidden] 是否忽略是否是隐藏文件
 * @param[tier] 获取的层级，负数时不限定层级
 */
@JvmOverloads
fun File.allFiles(ignoreIsHidden: Boolean = false, tier: Int = -1): ArrayList<File> {
    val result = ArrayList<File>()
    if (tier != 0) {
        if (this.isExistsFile(ignoreIsHidden)) {
            result.add(this)
        } else if (this.isExistsFolder(ignoreIsHidden)) {
            val files = this.listFiles()
            if (files != null)
                for (file in files)
                    result.addAll(file.allFiles(ignoreIsHidden, if (tier < 0) -1 else tier - 1))
        }
    }
    return result
}

/**
 * 获取文件大小，文件夹则把其中所有文件大小加起来
 *
 * @param[ignoreIsHidden] 是否忽略是否是隐藏文件
 */
@JvmOverloads
fun File.getFileSize(ignoreIsHidden: Boolean = false): Long {
    var result = 0L
    if (this.isExistsFile(ignoreIsHidden)) {
        result += this.length()
    } else if (this.isExistsFolder(ignoreIsHidden)) {
        val files = this.listFiles()
        if (files.isNotNullOrEmpty())
            for (file in files!!)
                result += file.getFileSize()
    }
    return result
}

/**
 * 批量更改哔哩哔哩下载的视频名
 *
 * @param[regex] 匹配文件名的正则
 * @param[ignoreHidden] 是否忽略隐藏文件
 */
@JvmOverloads
fun File.biLiBiLi(regex: Regex = "( )(\\d+.*?)(\\))".toRegex(), ignoreHidden: Boolean = true) {
    if (ignoreHidden && this.isHidden) return
    if (this.isFile) {
        val filePath = this.parentFile.absolutePath
        val fileName = this.nameWithoutExtension
        val fileExtension = this.extension
        val find = regex.find(fileName)
        if (find != null) this.renameTo(File("$filePath${File.separator}${find.groupValues[2]}.$fileExtension"))
    } else if (this.isDirectory) {
        val files = this.listFiles()
        if (files != null) for (file in files) file.biLiBiLi(regex, true)
    }
}
// endregion